package cn.redragon.soa.security;

import cn.redragon.soa.common.core.constant.AuthConstant;
import cn.redragon.soa.common.core.util.jwt.RsaJwtTokenVerifier;
import cn.redragon.soa.common.web.util.SecurityUtil;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * Replace with {@link BearerTokenAuthenticationFilter}
 */
@Slf4j
@Deprecated
public class CommonJwtFilter extends OncePerRequestFilter {

    private final RsaJwtTokenVerifier tokenVerifier;
    private final RequestMatcher requestMatcher;

    public CommonJwtFilter(final RsaJwtTokenVerifier tokenVerifier, final RequestMatcher requestMatcher) {
        this.tokenVerifier = tokenVerifier;
        this.requestMatcher = requestMatcher;
    }

    @Override
    protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws
        ServletException, IOException {
        if (tokenVerifier == null || !requestMatcher.matches(request)) {
            filterChain.doFilter(request, response);
            return;
        }

        String bearerToken = request.getHeader(AuthConstant.AUTH_HEADER);
        if (StringUtils.isBlank(bearerToken) || !bearerToken.startsWith(AuthConstant.BEARER_AUTH_PREFIX)) {
            filterChain.doFilter(request, response);
            return;
        }
        String token = bearerToken.replace(AuthConstant.BEARER_AUTH_PREFIX, StringUtils.EMPTY);

        if (this.tokenVerifier.isTokenExpired(token)) {
            throw new AccountExpiredException(token);
        }

        // valid jwt token
        String userName = tokenVerifier.getSubject(token);
        Collection<String> roles = tokenVerifier.getUserRole(token);

        CommonAuthenticationToken authenticationToken = new CommonAuthenticationToken(userName, token, roles);

        SecurityUtil.saveAuthentication(authenticationToken);

        filterChain.doFilter(request, response);
    }
}
